//
//  AUAssistiveTouch.swift
//  GLUZSwift
//
//  Created by yu on 2025/4/11.
//

import Foundation
import UIKit
import Kingfisher

// MARK: - 辅助布局类型
struct AUAssistiveTouchLayout: OptionSet {
    let rawValue: Int
    
    static let left   = AUAssistiveTouchLayout(rawValue: 1 << 0)
    static let right  = AUAssistiveTouchLayout(rawValue: 1 << 1)
    static let top    = AUAssistiveTouchLayout(rawValue: 1 << 2)
    static let bottom = AUAssistiveTouchLayout(rawValue: 1 << 3)
    
    static let defaultMask: AUAssistiveTouchLayout = [.left, .right, .top, .bottom]
}

final class AUAssistiveTouch {
    
    // MARK: - 单例
    static let shared = AUAssistiveTouch()
    private init() {
//        setupNotifications()
        setupTouchView()
    }
    
    // MARK:属性
    private var touchView: UIView!
    private var menuBtn: UIButton!
    private var animationImageView: AnimatedImageView!
    var clickClosure: (()  -> Void)?
    
    private var layout: AUAssistiveTouchLayout = [ .right]
    
    private var panGesture: UIPanGestureRecognizer!
    
    private var isShouldClick = true
    
    var maxArea: CGRect?

    static func addTouchView(on parent: UIView) {
        parent.addSubview(shared.touchView)
    }
    
    // MARK: - 公开方法
    static func setHidden(_ hidden: Bool) {
        shared.setHidden(hidden)
    }
    
    static func setCurrentLayout(layout :AUAssistiveTouchLayout) {
        shared.setCurrentLayout(layout: layout)
    }
    
    static func setLocation(with point: CGPoint) {
        shared.setTouchViewFrame(with: point)
    }
    
    func setTouchViewFrame(with point: CGPoint) {
        UIView.animate(withDuration: Constants.animationDuration) {
            self.touchView.frame = self.adjustedFrame(for: point)
        }
    }
    
    
    func setCurrentLayout(layout :AUAssistiveTouchLayout) {
        guard layout.contains(layout)  else { return }
        
        var touchViewFrame: CGRect = CGRect(x: 0, y: UIScreen.main.bounds.height / 2, width: self.touchView.bounds.width, height: self.touchView.bounds.height)
        switch layout {
        case .left:
            touchViewFrame = adjustedFrame(for: CGPoint(x: 0, y: UIScreen.main.bounds.height / 2))
            
        case .right:
            touchViewFrame = adjustedFrame(for: CGPoint(x: UIScreen.main.bounds.width, y: UIScreen.main.bounds.height / 2))
        case .top:
            touchViewFrame = adjustedFrame(for: CGPoint(x: UIScreen.main.bounds.width / 2, y: 0))
        case .bottom:
            touchViewFrame = adjustedFrame(for: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height))
        default:
            break
        }
        
        UIView.animate(withDuration: Constants.animationDuration) {
            self.touchView.frame = touchViewFrame
//                self.touchView.alpha = 0.3
        }
    }
    
    // MARK: - 位置调整中心点逻辑
    private func adjustedFrame(for point: CGPoint) -> CGRect {
        let screenSize = UIScreen.main.bounds.size
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height
        let midX = screenWidth / 2
        let midY = screenHeight / 2
        
        let touchWidth = touchView.bounds.width
        let touchHeight = touchView.bounds.height
        var adjustedFrame = CGRect(x: point.x, y: point.y , width: touchWidth, height: touchHeight)
        
        var minX: CGFloat = 0
        var maxX = screenWidth
        var minY: CGFloat = 64
        var maxY = screenHeight
        if let maxArea = self.maxArea {
            minX = max(minX, maxArea.minX)
            maxX = min(maxX, maxArea.maxX)
            minY = max(minY, maxArea.minY)
            maxY = min(maxY, maxArea.maxY)
        }
        
        let limitX = max(minX, min(maxX - touchWidth, point.x))
        let limitY = max(minY, min(maxY - touchHeight, point.y))
        
        // 横向调整
        if layout.contains(.left) && layout.contains(.right) {
            //            adjustedFrame.x = (point.x <= midX) ? 0 : screenWidth
            let x = limitX <= midX ? 0 : (maxX - touchWidth)
            
            adjustedFrame = adjustedFrame.withX(x).withY(limitY)
            
        } else if layout.contains(.left) {
            //            adjustedFrame.x = 0
            adjustedFrame = adjustedFrame.withX(minX).withY(limitY)
        } else if layout.contains(.right) {
            //            adjustedFrame.x = screenWidth
            adjustedFrame = adjustedFrame.withMaxX(screenWidth).withY(limitY)
        }
        
        // 纵向调整
        if layout.contains(.top) && layout.contains(.bottom) {
            
            //            adjustedFrame.y = (point.y <= midY) ? 64 : screenHeight - 64
            let y = limitY <= midY ? minY : maxY - touchHeight
            adjustedFrame = adjustedFrame.withX(limitX).withY(y)
        } else if layout.contains(.top) {
            //            adjustedFrame.y = 64
            adjustedFrame = adjustedFrame.withX(limitX).withY(minY)
        } else if layout.contains(.bottom) {
            adjustedFrame = adjustedFrame.withX(limitX).withMaxY(maxY)
        }
        //        else {
        //            adjustedFrame.y = max(64, min(screenHeight - 64, point.y))
        //        }
        
        // 刘海屏适配
        //        if hasNotch {
//    }
        
        let orientation = UIApplication.shared.statusBarOrientation
        if (adjustedFrame.minX == 0 &&
            orientation == .landscapeRight &&
            (64...290).contains(adjustedFrame.minY)) {
            
        } else if (adjustedFrame.maxX == screenWidth &&
                   orientation == .landscapeLeft &&
                   (64...290).contains(adjustedFrame.minY)) {
            let y = (adjustedFrame.minY < midY) ? 80.0 : 295.0
            adjustedFrame = adjustedFrame.withY(y)
        }
//        }
        
        return adjustedFrame
    }
    
    // MARK: - 常量
    private enum Constants {
        static let assistiveWidth: CGFloat = 78
//        static let menuItemWidth: CGFloat = 50
        static let animationDuration: TimeInterval = 0.25
    }
    
    // MARK: - 配置视图
    private func setupTouchView() {
        touchView = UIView(frame: CGRect(
            x: UIScreen.main.bounds.width - 84,
            y: 64,
            width: 84,
            height: 65
        ))
        touchView.backgroundColor = .clear
        
        animationImageView = AnimatedImageView()
        touchView.addSubview(animationImageView)
        //animationImageView的上下左右与父控件约束
        animationImageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            animationImageView.topAnchor.constraint(equalTo: touchView.topAnchor),
            animationImageView.leadingAnchor.constraint(equalTo: touchView.leadingAnchor),
            animationImageView.trailingAnchor.constraint(equalTo: touchView.trailingAnchor),
            animationImageView.bottomAnchor.constraint(equalTo: touchView.bottomAnchor)
        ])
        
        if let path = Bundle.main.path(forResource: "icon_translation", ofType: "gif") {
        
            let fileURL = URL(fileURLWithPath: path)
            DispatchQueue.main.async {
                self.animationImageView.kf.setImage(with: fileURL)
            }
            
        }
        
        menuBtn = UIButton(type: .custom)
        menuBtn.frame = touchView.bounds
//        menuBtn.setImage(UIImage(named: "icon_assistiveTouch"), for: .normal)
        
//        menuBtn.layer.cornerRadius = Constants.assistiveWidth/2
//        menuBtn.clipsToBounds = true
        menuBtn.addTarget(self, action: #selector(buttonClicked(_:)), for: .touchUpInside)
        
        touchView.addSubview(menuBtn)
        
        panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        panGesture.delaysTouchesBegan = true
        touchView.addGestureRecognizer(panGesture)
        
        layout = [ .right]
        touchView.isUserInteractionEnabled = true
    }
//    // MARK: - 通知处理
//    private func setupNotifications() {
//        NotificationCenter.default.addObserver(
//            self,
//            selector: #selector(orientationChanged(_:)),
//            name: UIApplication.didChangeStatusBarOrientationNotification,
//            object: nil
//        )
//    }

    // MARK: - 显示/隐藏逻辑
    private func setHidden(_ hidden: Bool) {
        DispatchQueue.main.async {
//            if hidden {
//                touchView.isHidden = hidden
//            } else {
            self.touchView.isHidden = hidden
//                self.touchView.alpha = 0.3
//                self.touchView.frame.origin = CGPoint(x: -Constants.assistiveWidth/2, y: Constants.assistiveWidth+10)
//                UIApplication.topViewController?.view.addSubview(self.touchView)
//            }
        }
    }
    
    // MARK: - 拖动手势处理
    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
        guard let superView = touchView.superview else { return }
        
        let location = gesture.location(in: superView)
        switch gesture.state {
        case .began:
            touchView.alpha = 1
        case .changed:
            touchView.center = location
        case .ended, .cancelled:
            setTouchViewFrame(with: location)
        default: break
        }
    }
    
    // MARK: - 位置调整中心点逻辑
    private func adjustedPosition(for point: CGPoint) -> CGPoint {
        let screenSize = UIScreen.main.bounds.size
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height
        let midX = screenWidth / 2
        let midY = screenHeight / 2
        
        var adjustedPoint = point
        
        // 横向调整
        if layout.contains(.left) && layout.contains(.right) {
            adjustedPoint.x = (point.x <= midX) ? 0 : screenWidth
        } else if layout.contains(.left) {
            adjustedPoint.x = 0
        } else if layout.contains(.right) {
            adjustedPoint.x = screenWidth
        }
        
        // 纵向调整
        if layout.contains(.top) && layout.contains(.bottom) {
            adjustedPoint.y = (point.y <= midY) ? 64 : screenHeight - 64
        } else if layout.contains(.top) {
            adjustedPoint.y = 64
        } else if layout.contains(.bottom) {
            adjustedPoint.y = screenHeight - 64
        } else {
            adjustedPoint.y = max(64, min(screenHeight - 64, point.y))
        }
        
        // 刘海屏适配
//        if hasNotch {
            let orientation = UIApplication.shared.statusBarOrientation
            if (adjustedPoint.x == 0 && orientation == .landscapeRight && (64...290).contains(adjustedPoint.y)) ||
               (adjustedPoint.x == screenWidth && orientation == .landscapeLeft && (64...290).contains(adjustedPoint.y)) {
                adjustedPoint.y = (adjustedPoint.y < midY) ? 80 : 295
            }
//        }
        
        return adjustedPoint
    }
    
    // MARK: - 按钮点击处理
    @objc private func buttonClicked(_ sender: UIButton) {
        clickClosure?()
//        guard isShouldClick else { return }

    }
}



extension CGRect {
    var withX: (CGFloat) -> CGRect {
        { CGRect(x: $0, y: origin.y, width: width, height: height) }
    }
    
    var withY: (CGFloat) -> CGRect {
        { CGRect(x: origin.x, y: $0, width: width, height: height) }
    }
    
    var withWidth: (CGFloat) -> CGRect {
        { CGRect(x: origin.x, y: origin.y, width: $0, height: height) }
    }
    
    var withHeight: (CGFloat) -> CGRect {
        { CGRect(x: origin.x, y: origin.y, width: width, height: $0) }
    }

    var withMaxX: (CGFloat) -> CGRect {
        { CGRect(x: $0 - width , y: origin.y, width: width, height: height) }
    }
    
    var withMaxY: (CGFloat) -> CGRect {
        { CGRect(x: origin.x, y: $0 - height, width: width, height: height) }
    }
}
